//将类数组对象转换为数组
function array(a,n){
  return Array.prototype.slice.call(a,n||0);
}

//创建形参从左边起靠的部分函数
function partial_left(f){
  var args = arguments;
  return function(){
    var a = array(args,1);
    a = a.concat(array(arguments));
    return f.apply(this,a);
  };
}

//创建形参从右边起靠的部分函数
function partial_right(f){
  var args = arguments;
  return function(){
    var a = array(arguments);
    a = a.concat(array(args,1));
    return f.apply(this,a);
  };
}

//创建部分函数，如果形参为undefined，则用实参来填充
function partial(f){
  var args = arguments;
  return function(){
    var a = array(args,1);
    var i = 0,j = 0;
    for(;i<a.length;i++)
      if(a[i] === undefined)
        a[i] = arguments[j++];
    a = a.concat(array(arguments,j));
    return f.apply(this,a);
  };
}

//创建函数f(g())
function compose(f,g){
  return function(){
    return f.call(this,g.apply(this,arguments));
  };
}

//取得对象本身的属性名数组
function get_propert_names(obj){
  return Object.getOwnPropertyNames(obj);
}

//返回对象的类
function classof(o){
  return Object.prototype.toString.call(o).slice(8,-1);
}

//返回函数的名字(可能为空字符串)，不是函数返回null
Function.prototype.get_name = function(){
  if ("name" in this) return this.name;
  //或者r = /function\s*(.*?)\(/;
  var r = /function\s*([^(]*)\(/;
  return this.name = this.toString().match(r)[1];
}

//返回对象的类型
function type(o){
  var t,c,n;  //type,class,name

  //可以不显式判断undeinfed，因为typeof undefined 返回 "undefined"
  //if(o === undefined) return "undefined";
  //但typeof null 却返回 "object"
  if(o === null) return "null";
  if(o !== o) return "nan";
  //如果typeof返回可以辨认则返回这个值
  if((t = typeof o) !== "object") return t;
  //如果classof返回可以辨认则返回这个值
  if((c = classof(o)) !== "Object") return c;
  //如果对象构造函数名字存在则返回这个值
  if(o.constructor && typeof o.constructor === "function" &&
    (n = o.constructor.get_name())) return n;
  //其他类型无法辨认，一律返回"Object"
  return "Object";
}
